﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using Lamex.Library;
using System.IO;
using System.Drawing.Imaging;
using System.Threading;
using Lamex.Library.CommonClass;

namespace Lamex.mTools.UI
{
    public partial class frmTL_Images_Cropping : frmBaseChild
    {
        public delegate void StartCutPicture(string Msg,int m,int total);
        //定义一个委托变量
        public StartCutPicture startCutPicture;
        bool isInterrupt = true;
        private static int txtWidth = 5;
        private static int txtHeight = 5;
        FileInfo[] filePathList = new FileInfo[] { };
        public frmTL_Images_Cropping()
        {
            startCutPicture = new StartCutPicture(UpdateLableMethod);
            InitializeComponent();
        }
        public void UpdateLableMethod(string msg,int m, int total)
        {
            progressBar.Properties.Maximum = total;
            label1.Text = msg;
            progressBar.Position = m;
            
        }
        private void buttonPathOld_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog folder = new System.Windows.Forms.FolderBrowserDialog();
            folder.ShowDialog();
            if (string.IsNullOrEmpty(folder.SelectedPath)) return;
            txtPath.Text = folder.SelectedPath;
            DirectoryInfo root = new DirectoryInfo(txtPath.Text);
            filePathList = root.GetFiles();
            //labelControl1.Text = "选中图片文件数量：" + filePathList.Count();

        }

        private void buttonPathNew_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog folder = new System.Windows.Forms.FolderBrowserDialog();
            folder.ShowDialog();
            if (string.IsNullOrEmpty(folder.SelectedPath)) return;
            txtSavePath.Text = folder.SelectedPath;
        }

        private void buttonImageCropping_Click(object sender, EventArgs e)
        {
            //SplashScreenTool.ShowSplashScreen(typeof(WaitForm1));

            Thread objThread = new Thread(new ThreadStart(delegate
            {
                CutPictureList();
            }));
            objThread.Start();


            //SplashScreenTool.CloseSplashScreen();
        }


        private void CutPictureList()
        {
            if (string.IsNullOrEmpty(txtPath.Text))
            {
                XtraMessageBox.Show("原图路径不能为空！");
                return;
            }
            if (string.IsNullOrEmpty(txtSavePath.Text))
            {
                XtraMessageBox.Show("保存路径不能为空！");
                return;
            }
            
            List<string> dirPathList = new List<string>();
            dirPathList.Clear();
            DirectoryInfo dir = new DirectoryInfo(txtPath.Text);
            //获取相关文件路径
            DirectoryInfo[] dirs = dir.GetDirectories();
            foreach (DirectoryInfo info in dirs)
            {
                string path = info.FullName.Replace(txtPath.Text,"");
                dirPathList.Add(path);
                GetDirs(info, dirPathList);
            }
            dirPathList.Add("");
            //开始处理文件
            List<string> dirPath = dirPathList.Distinct().ToList();
            foreach (string filePath in dirPath)
            {
                if (isInterrupt == false)
                    break;
                string targetPath = txtSavePath.Text;
                //if (!Directory.Exists(targetPath))
                //{
                //    Directory.CreateDirectory(targetPath);
                //}

                string sourcePath = txtPath.Text + filePath;
                Bitmap showBitmap = null;
                FileInfo files = new FileInfo(sourcePath);
                DirectoryInfo root = new DirectoryInfo(sourcePath);
                 string name =System.IO.Path.GetFileName(sourcePath);
                filePathList = root.GetFiles("*.jpg");
                int m = 1;
                int total = filePathList.Count();
                //progressBar.Properties.Maximum = total;
                object[] objList = new object[3];
                objList[0] = "开始处图片数量！";
                objList[1] = 0;
                objList[2] = total;
                isInterrupt = true;
                this.BeginInvoke(startCutPicture, objList);
                foreach (FileInfo info in filePathList)
                {
                    if (isInterrupt == false)
                        break;
                    CutPicture(info.FullName, info.Name, showBitmap, targetPath);
                    string msg = "文件夹:" + name + "图片裁剪:" + "已完成图片数量：" + m + "|未完成图片数量：" + (total - m);
                    objList[0] = msg;
                    objList[1]= m;
                    objList[2] = total;
                    this.BeginInvoke(startCutPicture, objList);
                    m++;
                    Thread.Sleep(100);

                }
                objList[0] ="图片处理完成";
                objList[1] = 0;
                objList[2] = total;
                this.BeginInvoke(startCutPicture, objList);
            }
            XtraMessageBox.Show("成功剪裁！");
        }

        private void  GetDirs(DirectoryInfo info,List<string> lst)
        {
            DirectoryInfo[] dirs = info.GetDirectories();
            foreach(DirectoryInfo dirInfo in dirs)
            {
                string path = info.FullName.Replace(txtPath.Text, "");
                lst.Add(path);
                GetDirs(dirInfo, lst);
            }
        }
        public void CutPicture( string FilePath,string FileName, Bitmap showBitmap,string targetPath)
        {
            Bitmap srcBitmap = new Bitmap(FilePath);
            showBitmap = RGBBitMap(srcBitmap);
            
            ImageFormat format = ImageFormat.Jpeg;
            if(showBitmap!=null)
                showBitmap.Save(targetPath + "\\" + FileName);
        }
        public static Bitmap RGBBitMap(Bitmap srcBitmap)
        {
            try
            {
                List<XYPoint> pointList = new List<XYPoint>();
                int wide = srcBitmap.Width;
                int height = srcBitmap.Height;
                Rectangle rect = new Rectangle(0, 0, 100, 100);
                //将Bitmap锁定到系统内存中,获得BitmapData
                BitmapData srcBmData = srcBitmap.LockBits(rect,
                          ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
                //创建Bitmap
                Bitmap dstBitmap = CreateGrayscaleImage(wide, height);//这个函数在后面有定义
                BitmapData dstBmData = dstBitmap.LockBits(rect,
                          ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
                //位图中第一个像素数据的地址。它也可以看成是位图中的第一个扫描行
                System.IntPtr srcPtr = srcBmData.Scan0;
                System.IntPtr dstPtr = dstBmData.Scan0;
                //将Bitmap对象的信息存放到byte数组中
                int src_bytes = srcBmData.Stride * height;
                byte[] srcValues = new byte[src_bytes];
                int dst_bytes = dstBmData.Stride * height;
                byte[] dstValues = new byte[dst_bytes];
                //复制GRB信息到byte数组
                System.Runtime.InteropServices.Marshal.Copy(srcPtr, srcValues, 0, src_bytes);
                System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes);
                //根据Y=0.299*R+0.114*G+0.587B,Y为亮度
                byte oldRgbTemp = new byte();
                for (int i = 0; i < height; i++)
                {

                    for (int j = 0; j < wide; j++)
                    {
                        //只处理每行中图像像素数据,舍弃未用空间
                        //注意位图结构中RGB按BGR的顺序存储
                        int k = 3 * j;

                        byte RgbTemp = (byte)(srcValues[i * srcBmData.Stride + k + 2] * .299
                             + srcValues[i * srcBmData.Stride + k + 1] * .587
    + srcValues[i * srcBmData.Stride + k] * .114);
                        if (i != 0 && j != 0)
                        {
                            if (RgbTemp != oldRgbTemp)
                            {
                                XYPoint model = new XYPoint();
                                model.xPoint = j;
                                model.yPoint = i;
                                pointList.Add(model);
                                oldRgbTemp = RgbTemp;
                            }


                        }
                        else
                        {
                            oldRgbTemp = RgbTemp;
                        }

                        //dstValues[i * dstBmData.Stride + j] = temp;
                    }
                }
                //收集各个点的数据
                var list = pointList;
                int minYPoint = pointList.Min(p => p.yPoint);
                int maxYPoint = pointList.Max(p => p.yPoint);
                int minXPoint = pointList.Min(p => p.xPoint);
                int maxXPoint = pointList.Max(p => p.xPoint);
                //确定图片位置
                Point pos = new Point();
                //pos.X = minXPoint - 10;
                //pos.Y = minYPoint - 10;
                int cutWidth = maxXPoint - minXPoint;
                int cutHeight = maxYPoint - minYPoint;


                int maxLenght = 0;
                if (cutWidth > cutHeight)
                    maxLenght = cutWidth;
                else
                    maxLenght = cutHeight;
                decimal ParaPercent = Math.Round(decimal.Parse(txtWidth.ToString()) / decimal.Parse((100.0).ToString()), 2);
                decimal value=decimal.Parse(maxLenght.ToString()) * ParaPercent;
                maxLenght = (int)value;
                //cutWidth =maxXPoint - minXPoint+maxLenght;
                //cutHeight = maxYPoint - minYPoint+maxLenght;


                int _cutWidth = maxXPoint - minXPoint+2*maxLenght;
                int _cutHeight = maxYPoint - minYPoint + 2 * maxLenght;
                pos.X = minXPoint - maxLenght;
                pos.Y = minYPoint - maxLenght;
                //System.Runtime.InteropServices.Marshal.Copy(dstPtr, dstValues, 0, dst_bytes);
                ////解锁位图
                srcBitmap.UnlockBits(srcBmData);
                dstBitmap.UnlockBits(dstBmData);
                //开始剪切图片
                Image cutImages = cutImage(srcBitmap, pos, _cutWidth, _cutHeight);
                Bitmap map = new Bitmap(cutImages);
                return map;
            }
            catch(Exception ex)
            {
                //XtraMessageBox.Show(ex.Message);
                return null;
            }
        }

        private static Image cutImage(Image SrcImage, Point pos, int cutWidth, int cutHeight)
        {

            Image cutedImage = null;

            //先初始化一个位图对象，来存储截取后的图像
            Bitmap bmpDest = new Bitmap(cutWidth, cutHeight, PixelFormat.Format32bppRgb);
            Graphics g = Graphics.FromImage(bmpDest);

            //矩形定义,将要在被截取的图像上要截取的图像区域的左顶点位置和截取的大小
            Rectangle rectSource = new Rectangle(pos.X, pos.Y, cutWidth, cutHeight);
            //矩形定义,将要把 截取的图像区域 绘制到初始化的位图的位置和大小
            //rectDest说明，将把截取的区域，从位图左顶点开始绘制，绘制截取的区域原来大小
            Rectangle rectDest = new Rectangle(0, 0, cutWidth, cutHeight);
            //第一个参数就是加载你要截取的图像对象，第二个和第三个参数及如上所说定义截取和绘制图像过程中的相关属性，第四个属性定义了属性值所使用的度量单位
            g.DrawImage(SrcImage, rectDest, rectSource, GraphicsUnit.Pixel);

            //在GUI上显示被截取的图像
            cutedImage = (Image)bmpDest;

            g.Dispose();
            GC.Collect();
            return cutedImage;

        }

        ///<summary>
        /// Create and initialize grayscale image
        ///</summary>
        public static Bitmap CreateGrayscaleImage(int width, int height)
        {
            // create new image
            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed);
            // set palette to grayscale
            SetGrayscalePalette(bmp);
            // return new image
            return bmp;
        }

        ///<summary>
        /// Set pallete of the image to grayscale
        ///</summary>
        public static void SetGrayscalePalette(Bitmap srcImg)
        {
            // check pixel format
            if (srcImg.PixelFormat != PixelFormat.Format8bppIndexed)
                throw new ArgumentException();
            // get palette
            ColorPalette cp = srcImg.Palette;
            // init palette
            for (int i = 0; i < 256; i++)
            {
                cp.Entries[i] = Color.FromArgb(i, i, i);
            }
            srcImg.Palette = cp;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            isInterrupt = false;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(textBox1.Text))
            {
                textBox1.Text = "0";
                return;
            }
            txtWidth = int.Parse(textBox1.Text);
            txtHeight = int.Parse(textBox1.Text);

        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!string.IsNullOrEmpty(textBox1.Text))//只显示数字
            {
                if (!char.IsDigit(e.KeyChar) && e.KeyChar != '\b')
                {
                    e.Handled = true;  //非以上键则禁止输入
                }
                if (e.KeyChar == '.' && textBox1.Text == "") e.Handled = true; //禁止第一个字符就输入小数点
                if (e.KeyChar == '.' && textBox1.Text.Contains(".")) e.Handled = true;
            }
        }
    }
}